<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>百度地图路径规划</title>
    <style>
        body { margin: 0; padding: 20px; font-family: Arial, sans-serif; }
        .container { max-width: 1200px; margin: 0 auto; }
        .search-box { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
        .input-group { position: relative; flex: 1; min-width: 250px; }
        input { width: 100%; padding: 10px 15px; border: 1px solid #ccc; border-radius: 4px; font-size: 16px; }
        button { margin-left: 25px; background-color: #38f; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }
        button:hover { background-color: #27e; }
        button:disabled { background-color: #999; cursor: not-allowed; }
        #map { width: 100%; height: 600px; border: 1px solid #ccc; border-radius: 4px; }
        .suggestion-box { position: absolute; top: 100%; left: 0; right: 0; background: white; border: 1px solid #ccc; border-top: none; border-radius: 0 0 4px 4px; max-height: 200px; overflow-y: auto; z-index: 100; display: none; }
        .suggestion-item { padding: 8px 15px; cursor: pointer; }
        .suggestion-item:hover { background-color: #f5f5f5; }
        .result-info { margin-top: 15px; padding: 10px; border: 1px solid #eee; border-radius: 4px; }
        .error-message { color: #f00; margin-top: 10px; }
        .loading { color: #666; margin-top: 10px; display: none; }
        .route-detail { margin-top: 10px; padding-left: 20px; line-height: 1.6; }
        .debug-info { margin-top: 10px; padding: 10px; background: #f9f9f9; border-radius: 4px; font-size: 14px; color: #666; }
        .api-key-box { margin-bottom: 20px; }
        .required::after { content: " *"; color: red; }
        
        /* 新增的布局样式 */
        .map-container {
            display: flex;
            gap: 20px;
            margin-bottom: 20px;
        }
        .map-content {
            flex: 3;
        }
        .info-content {
            flex: 1;
            min-width: 300px;
            height: 600px;
            overflow-y: auto;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>百度地图路径规划</h1>
        <div class="api-key-box">
            <div class="input-group">
                <input type="text" id="apiKey" value="Fd8VhlvggkJva2JNlP2UxvKWJQb4idtz" placeholder="请输入百度地图API Key（必填）">
            </div>
        </div>
        <div class="search-box">
            <div class="input-group">
                <input type="text" id="startPoint" placeholder="请输入起点（例如：北京天安门）">
                <div class="suggestion-box" id="startSuggestion"></div>
            </div>
            <div class="input-group">
                <input type="text" id="endPoint" placeholder="请输入终点（例如：北京颐和园）">
                <div class="suggestion-box" id="endSuggestion"></div>
            </div>
            <button id="searchBtn">查询路线</button>
        </div>
        
        <!-- 路线偏好 -->
        <div class="options-box" style="display: flex; gap: 20px; margin-bottom: 20px; flex-wrap: wrap;">
            <div class="route-preference">
                <label style="margin-right: 10px;">路线偏好：</label>
                <select id="routePreference" style="padding: 8px; border: 1px solid #ccc; border-radius: 4px;">
                    <option value="0">默认</option>
                    <option value="3">不走高速</option>
                    <option value="4">高速优先</option>
                    <option value="5">躲避拥堵</option>
                    <option value="6">少收费</option>
                    <option value="13">时间优先</option>
                    <!--
                    <option value="2">距离最短（估价场景）</option>
                    <option value="7">躲避拥堵 & 高速优先</option>
                    <option value="8">躲避拥堵 & 不走高速</option>
                    <option value="9">躲避拥堵 & 少收费</option>
                    <option value="10">躲避拥堵 & 不走高速 & 少收费</option>
                    <option value="11">不走高速 & 少收费</option>
                    <option value="12">距离优先</option>
                    -->
                </select>
            </div>
            <div class="cost-box" style="display: flex;gap: 10px;">
                <input type="number" id="unitPriceInput" placeholder="请输入单价（元/公里）" style="width: 180px; padding: 8px; border: 1px solid #ccc; border-radius: 4px;">
                <button id="calcCostBtn">计算费用</button>
            </div>
        </div>
        
        <!-- 地图和信息容器 -->
        <div class="map-container">
            <div class="map-content">
                <div id="map"></div>
            </div>
            <div class="info-content">
                <div class="loading" id="loading">正在规划路线，请稍候...</div>
                <div class="error-message" id="errorMsg"></div>
                <div class="result-info" id="costInfo"></div>
                <div class="result-info" id="routeInfo"></div>
                <div class="debug-info" id="debugInfo">调试信息：</div>
            </div>
        </div>
    </div>

    <!-- 百度地图API（请替换为自己的AK） -->
    <script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=HNPCuvp1WsvoWapcogapTvVBOyPIeiU7"></script>
    <!-- 路线规划类库 -->
    <script type="text/javascript" src="https://api.map.baidu.com/library/DrivingRoute/1.5/src/DrivingRoute_min.js"></script>
    <script type="text/javascript" src="https://api.map.baidu.com/library/WalkingRoute/1.5/src/WalkingRoute_min.js"></script>
    <script type="text/javascript" src="https://api.map.baidu.com/library/RidingRoute/1.5/src/RidingRoute_min.js"></script>
    
    <script>
        // 检查API加载状态
        if (typeof BMap === 'undefined') {
            document.getElementById('errorMsg').textContent = "百度地图API加载失败，请检查网络连接或API Key配置";
            console.error("百度地图API加载失败，请检查网络连接或API Key配置");
        }
        
        // 初始化地图（中心点设为北京，可根据需求修改）
        const map = new BMap.Map("map");
        const defaultPoint = new BMap.Point(116.404, 39.915);
        map.centerAndZoom(defaultPoint, 12);
        map.enableScrollWheelZoom(true); // 允许滚轮缩放
        
        // DOM元素
        const apiKeyInput = document.getElementById('apiKey');
        const startPointInput = document.getElementById('startPoint');
        const endPointInput = document.getElementById('endPoint');
        const searchBtn = document.getElementById('searchBtn');
        const routeInfo = document.getElementById('routeInfo');
        const errorMsg = document.getElementById('errorMsg');
        const debugInfo = document.getElementById('debugInfo');

        const routePreference = document.getElementById('routePreference');
        const unitPriceInput = document.getElementById('unitPriceInput');
        const calcCostBtn = document.getElementById('calcCostBtn');
        const costInfo = document.getElementById('costInfo');
        
        // loading元素可能在某些情况下为null，需要在使用时检查
        function getLoadingElement() {
            return document.getElementById('loading');
        }
        
        // 存储起点/终点信息（坐标+地址）
        let start = { point: null, address: '' };
        let end = { point: null, address: '' };
        
        // 防抖功能实现
        function debounce(func, wait) {
            let timeout;
            return function executedFunction(...args) {
                const later = () => {
                    clearTimeout(timeout);
                    func(...args);
                };
                clearTimeout(timeout);
                timeout = setTimeout(later, wait);
            };
        }
        
        // 按钮状态管理
        function setButtonLoading(button, isLoading, originalText) {
            if (isLoading) {
                button.disabled = true;
                button.textContent = '处理中...';
            } else {
                button.disabled = false;
                button.textContent = originalText;
            }
        }
        
        // 调试日志输出
        function logDebug(msg) {
            debugInfo.innerHTML += `<p>${new Date().toLocaleTimeString()}：${msg}</p>`;
            console.log("[调试] " + msg);
        }
        
        // 时间格式化函数（秒转为时分秒）
        function formatDuration(seconds) {
            const hours = Math.floor(seconds / 3600);
            const minutes = Math.floor((seconds % 3600) / 60);
            const secs = seconds % 60;
            
            if (hours > 0) {
                return `${hours}小时${minutes}分钟${secs}秒`;
            } else if (minutes > 0) {
                return `${minutes}分钟${secs}秒`;
            } else {
                return `${secs}秒`;
            }
        }
        
        // 地址解析（带重试机制，确保获取坐标）
        function getPointFromAddress(address, city, retry = 0) {
            return new Promise((resolve, reject) => {
                if (retry > 2) {
                    reject(new Error(`地址解析失败：${address}`));
                    return;
                }
                const myGeo = new BMap.Geocoder();
                myGeo.getPoint(address, (point) => {
                    if (point) {
                        logDebug(`解析成功：${address} → (${point.lng.toFixed(6)}, ${point.lat.toFixed(6)})`);
                        resolve(point);
                    } else {
                        logDebug(`解析失败（第${retry+1}次重试）：${address}`);
                        setTimeout(() => {
                            getPointFromAddress(address, city, retry + 1).then(resolve).catch(reject);
                        }, 500);
                    }
                }, city);
            });
        }
        
        // 创建地址自动完成（输入提示）
        function createAutocomplete(inputId, isStart) {
            const input = document.getElementById(inputId);
            const suggestionBox = document.getElementById(inputId + "Suggestion");
            
            const ac = new BMap.Autocomplete({
                input: inputId,
                location: map
            });
            
            // 显示提示框
            ac.addEventListener("onhighlight", () => {
                if (suggestionBox) suggestionBox.style.display = "block";
            });
            
            // 点击外部隐藏提示框
            document.addEventListener('click', (e) => {
                if (suggestionBox && !input.parentElement.contains(e.target)) {
                    suggestionBox.style.display = "none";
                }
            });
            
            // 选择提示项后解析坐标
            ac.addEventListener("onconfirm", async (e) => {
                try {
                    const value = e.item.value;
                    const address = `${value.province}${value.city}${value.district}${value.street}${value.business}`;
                    input.value = address;
                    
                    // 等待坐标解析完成
                    const point = await getPointFromAddress(address, value.city);
                    if (isStart) {
                        start = { point, address };
                    } else {
                        end = { point, address };
                    }
                    if (suggestionBox) suggestionBox.style.display = "none";
                    errorMsg.textContent = "";
                } catch (err) {
                    logDebug("提示项解析失败：" + err.message);
                    errorMsg.textContent = `${isStart ? '起点' : '终点'}地址无效，请重新选择`;
                }
            });
            return ac;
        }
        
        // 初始化自动完成
        const startAutoComplete = createAutocomplete("startPoint", true);
        const endAutoComplete = createAutocomplete("endPoint", false);
        
        // 手动输入地址解析
        async function handleManualAddress(input, isStart) {
            const address = input.value.trim();
            if (!address) {
                isStart ? (start = { point: null, address: '' }) : (end = { point: null, address: '' });
                return Promise.resolve();
            }
            
            // 显示解析中状态
            const loadingElement = getLoadingElement();
            if (loadingElement) {
                loadingElement.textContent = `${isStart ? '起点' : '终点'}地址解析中，请稍候...`;
                loadingElement.style.display = "block";
            }
            
            try {
                const point = await getPointFromAddress(address);
                if (isStart) {
                    start = { point, address };
                } else {
                    end = { point, address };
                }
                logDebug(`手动解析${isStart ? '起点' : '终点'}成功`);
                
                // 隐藏解析中状态
                if (loadingElement) {
                    loadingElement.style.display = "none";
                }
                
                return Promise.resolve();
            } catch (err) {
                logDebug("手动解析失败：" + err.message);
                errorMsg.textContent = `${isStart ? '起点' : '终点'}地址无法识别，请检查`;
                
                // 隐藏解析中状态
                if (loadingElement) {
                    loadingElement.style.display = "none";
                }
                
                return Promise.reject(err);
            }
        }
        
        // 绑定手动输入事件
        startPointInput.addEventListener('blur', () => handleManualAddress(startPointInput, true));
        endPointInput.addEventListener('blur', () => handleManualAddress(endPointInput, false));
        
        // 核心：路线规划函数
        async function planRoute() {
            // 防止重复点击
            if (searchBtn.disabled) {
                return;
            }
            
            // 设置按钮加载状态
            setButtonLoading(searchBtn, true, '查询路线');
            
            // 重置状态
            errorMsg.textContent = "";
            routeInfo.innerHTML = "";
            debugInfo.innerHTML = "调试信息：";
            map.clearOverlays(); // 清除之前的路线和标记
            
            // 验证API Key
            const apiKey = apiKeyInput.value.trim();
            if (!apiKey) {
                errorMsg.textContent = "请先输入百度地图API Key";
                apiKeyInput.focus();
                setButtonLoading(searchBtn, false, '查询路线');
                return;
            }
            
            // 检查起点输入并触发解析
            if (startPointInput.value.trim() && !start.point) {
                try {
                    await handleManualAddress(startPointInput, true);
                } catch (err) {
                    errorMsg.textContent = "起点地址解析失败，请检查后重试";
                    setButtonLoading(searchBtn, false, '查询路线');
                    return;
                }
            }
            
            // 检查终点输入并触发解析
            if (endPointInput.value.trim() && !end.point) {
                try {
                    await handleManualAddress(endPointInput, false);
                } catch (err) {
                    errorMsg.textContent = "终点地址解析失败，请检查后重试";
                    setButtonLoading(searchBtn, false, '查询路线');
                    return;
                }
            }
            
            // 验证起点终点
            if (!start.point) {
                errorMsg.textContent = "请先选择有效的起点（输入地址后请确保已选择或确认）";
                startPointInput.focus();
                setButtonLoading(searchBtn, false, '查询路线');
                return;
            }
            if (!end.point) {
                errorMsg.textContent = "请先选择有效的终点（输入地址后请确保已选择或确认）";
                endPointInput.focus();
                setButtonLoading(searchBtn, false, '查询路线');
                return;
            }
            if (start.point.lng === end.point.lng && start.point.lat === end.point.lat) {
                errorMsg.textContent = "起点和终点不能相同";
                setButtonLoading(searchBtn, false, '查询路线');
                return;
            }
            
            // 获取路线偏好选项
            const routeTacticsValue = parseInt(routePreference.value);
            
            // 显示加载状态
            const loadingElement = getLoadingElement();
            if (loadingElement) {
                loadingElement.textContent = "正在规划路线，请稍候...";
                loadingElement.style.display = "block";
            }
            logDebug("开始规划路线...");
            
            // 准备请求数据
            const requestData = {
                origin: `${start.point.lat},${start.point.lng}`,
                destination: `${end.point.lat},${end.point.lng}`,
                route_type: "driving",  // 默认为驾车路线
                tactics: routeTacticsValue.toString(),
                ak: apiKey
            };
            
            logDebug(`请求数据：${JSON.stringify(requestData)}`);
            
            // 调用后端接口获取路线信息
            fetch('/api/map/sdk/baidu/mapSdkBaidu/noGetwayReadRoute', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(requestData)
            })
            .then(response => response.json())
            .then(data => {
                // 隐藏加载状态
                if (loadingElement) {
                    loadingElement.style.display = "none";
                }
                setButtonLoading(searchBtn, false, '查询路线');
                
                if (data.code === 0) {
                    // 处理成功响应
                    const routeData = data.data;
                    
                    // 显示路线在地图上
                    displayRouteOnMap(routeData, "driving");
                    
                    // 显示路线信息
                    displayRouteInfo(routeData);
                } else {
                    // 处理错误响应
                    errorMsg.textContent = `路线规划失败：${data.msg}`;
                    logDebug(`路线规划失败：${data.msg}`);
                }
            })
            .catch(error => {
                // 隐藏加载状态
                if (loadingElement) {
                    loadingElement.style.display = "none";
                }
                setButtonLoading(searchBtn, false, '查询路线');
                
                errorMsg.textContent = `请求失败：${error.message}`;
                logDebug(`请求失败：${error.message}`);
            });
        }
        
        // 在地图上显示路线
        function displayRouteOnMap(routeData, routeType) {
            // 清除之前的路线
            map.clearOverlays();
            
            // 标记起点和终点
            const startMarker = new BMap.Marker(start.point, {
                icon: new BMap.Icon("https://api.map.baidu.com/img/markers.png", new BMap.Size(23, 25), {
                    anchor: new BMap.Size(10, 25)
                })
            });
            
            const endMarker = new BMap.Marker(end.point, {
                icon: new BMap.Icon("https://api.map.baidu.com/img/markers.png", new BMap.Size(23, 25), {
                    anchor: new BMap.Size(10, 25),
                    imageOffset: new BMap.Size(0, 25)
                })
            });
            
            map.addOverlay(startMarker);
            map.addOverlay(endMarker);
            
            // 根据路线类型显示路线
            if (routeType === 'driving' && routeData.result && routeData.result.routes && routeData.result.routes.length > 0) {
                // 驾车路线
                const route = routeData.result.routes[0];
                if (route.steps) {
                    // 绘制路线
                    const points = [];
                    route.steps.forEach(step => {
                        if (step.path) {
                            const pathPoints = step.path.split(';').map(pointStr => {
                                const [lng, lat] = pointStr.split(',').map(Number);
                                return new BMap.Point(lng, lat);
                            });
                            points.push(...pathPoints);
                        }
                    });
                    
                    if (points.length > 0) {
                        const polyline = new BMap.Polyline(points, {
                            strokeColor: "#38f",
                            strokeWeight: 6,
                            strokeOpacity: 0.8
                        });
                        map.addOverlay(polyline);
                        map.setViewport(points); // 调整地图视野以适应路线
                    }
                }
            } else if (routeType === 'walking' && routeData.result && routeData.result.routes && routeData.result.routes.length > 0) {
                // 步行路线
                const route = routeData.result.routes[0];
                if (route.steps) {
                    // 绘制路线
                    const points = [];
                    route.steps.forEach(step => {
                        if (step.path) {
                            const pathPoints = step.path.split(';').map(pointStr => {
                                const [lng, lat] = pointStr.split(',').map(Number);
                                return new BMap.Point(lng, lat);
                            });
                            points.push(...pathPoints);
                        }
                    });
                    
                    if (points.length > 0) {
                        const polyline = new BMap.Polyline(points, {
                            strokeColor: "#38f",
                            strokeWeight: 6,
                            strokeOpacity: 0.8
                        });
                        map.addOverlay(polyline);
                        map.setViewport(points); // 调整地图视野以适应路线
                    }
                }
            } else if (routeType === 'riding' && routeData.result && routeData.result.routes && routeData.result.routes.length > 0) {
                // 骑行路线
                const route = routeData.result.routes[0];
                if (route.steps) {
                    // 绘制路线
                    const points = [];
                    route.steps.forEach(step => {
                        if (step.path) {
                            const pathPoints = step.path.split(';').map(pointStr => {
                                const [lng, lat] = pointStr.split(',').map(Number);
                                return new BMap.Point(lng, lat);
                            });
                            points.push(...pathPoints);
                        }
                    });
                    
                    if (points.length > 0) {
                        const polyline = new BMap.Polyline(points, {
                            strokeColor: "#38f",
                            strokeWeight: 6,
                            strokeOpacity: 0.8
                        });
                        map.addOverlay(polyline);
                        map.setViewport(points); // 调整地图视野以适应路线
                    }
                }
            }
        }
        
        // 显示路线信息
        function displayRouteInfo(routeData) {
            if (!routeData.result || !routeData.result.routes || routeData.result.routes.length === 0) {
                errorMsg.textContent = "未找到有效路线信息";
                return;
            }
            
            const route = routeData.result.routes[0];
            const distance = route.distance ? (route.distance / 1000).toFixed(1) : '未知';
            const duration = route.duration ? formatDuration(route.duration) : '未知';
            
            // 获取收费信息
            const toll = route.toll || '未知';  // 道路收费（元）
            const tollDistance = route.toll_distance ? (route.toll_distance / 1000).toFixed(1) : '未知';  // 收费路段里程（公里）
            const trafficLight = route.traffic_light || '未知';  // 红绿灯数量
            
            let stepsHtml = '<ol class="route-detail">';
            let totalSteps = 0;
            
            if (route.steps) {
                totalSteps = route.steps.length;
                route.steps.forEach(step => {
                    stepsHtml += `<li>${step.instruction || step.road_name || '未知路段'}</li>`;
                });
            }
            
            stepsHtml += '</ol>';
            
            // 显示结果
            routeInfo.innerHTML = `
                <p><strong>起点：</strong>${start.address}</p>
                <p><strong>终点：</strong>${end.address}</p>
                <p><strong>地图类型：</strong>百度地图</p>
                <p><strong>路线长度：</strong>${distance} 公里</p>
                <p><strong>预计耗时：</strong>${duration}</p>
                <p><strong>道路收费：</strong>${toll} 元</p>
                <p><strong>收费路段里程：</strong>${tollDistance} 公里</p>
                <p><strong>红绿灯数量：</strong>${trafficLight} 个</p>
                <p><strong>路线步骤（共${totalSteps}步）：</strong></p>
                ${stepsHtml}
            `;

            // 保存最新路线长度（公里），用于费用计算
            const distNum = parseFloat(distance);
            window.latestRouteDistanceKM = isNaN(distNum) ? undefined : distNum;
            if (costInfo) {
                costInfo.innerHTML = "";
            }
            
            logDebug(`路线显示成功：${distance}公里，${totalSteps}个步骤`);
        }
        
        // 计算费用：调用后端费用计算接口
        function calculateCost() {
            // 防止重复点击
            if (calcCostBtn.disabled) {
                return;
            }
            
            const distanceKM = window.latestRouteDistanceKM;
            if (distanceKM === undefined) {
                errorMsg.textContent = "请先查询路线以获取路线长度";
                return;
            }
            const unitPriceVal = parseFloat(unitPriceInput ? unitPriceInput.value : "");
            if (isNaN(unitPriceVal) || unitPriceVal <= 0) {
                errorMsg.textContent = "请输入有效的里程单价（元/公里）";
                if (unitPriceInput) unitPriceInput.focus();
                return;
            }
            
            // 设置按钮加载状态
            setButtonLoading(calcCostBtn, true, '计算费用');
            
            errorMsg.textContent = "";
            if (costInfo) costInfo.innerHTML = "正在计算费用...";

            fetch('/api/map/cost/mapCost/noGetwayReadCost', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    distance: distanceKM,
                    unitPrice: unitPriceVal
                })
            })
            .then(res => res.json())
            .then(data => {
                setButtonLoading(calcCostBtn, false, '计算费用');
                
                if (data.code === 0 && data.data) {
                    const result = data.data;
                    if (costInfo) {
                        costInfo.innerHTML = `
                            <p><strong>费用计算：</strong>${result.distance} 公里 × ${result.unitPrice} 元/公里 = <strong>${result.cost} 元</strong></p>
                        `;
                    }
                    logDebug(`费用计算成功：${result.cost}元`);
                } else {
                    const msg = data.msg || "费用计算失败";
                    if (costInfo) costInfo.innerHTML = `<p style=\"color:#f00;\">${msg}</p>`;
                    logDebug(`费用计算失败：${msg}`);
                }
            })
            .catch(err => {
                setButtonLoading(calcCostBtn, false, '计算费用');
                if (costInfo) costInfo.innerHTML = `<p style=\"color:#f00;\">请求失败：${err.message}</p>`;
                logDebug(`费用计算异常：${err.message}`);
            });
        }
        
        // 创建防抖版本的函数
        const debouncedPlanRoute = debounce(planRoute, 300);
        const debouncedCalculateCost = debounce(calculateCost, 300);
        
        // 绑定查询事件
        searchBtn.addEventListener('click', debouncedPlanRoute);
        
        // 绑定费用计算事件
        if (calcCostBtn) {
            calcCostBtn.addEventListener('click', debouncedCalculateCost);
        }
        
        // 路线偏好选项变化时自动查询路线
        routePreference.addEventListener('change', () => {
            // 只有在已有起点和终点的情况下才自动查询
            if (start.point && end.point) {
                logDebug('路线偏好已更改，自动重新规划路线');
                debouncedPlanRoute();
            }
        });
        
        // Enter键触发查询
        [startPointInput, endPointInput].forEach(input => {
            input.addEventListener('keypress', (e) => {
                if (e.key === 'Enter') {
                    debouncedPlanRoute();
                }
            });
        });

        // 页面加载检查
        window.addEventListener('load', () => {
            if (typeof BMap === 'undefined') {
                errorMsg.textContent = "百度地图API加载失败，请检查网络或AK";
                logDebug("API加载失败：未找到BMap对象");
            } else {
                logDebug("百度地图API加载成功，可开始使用");
            }
        });
    </script>
</body>
</html>